package com.shi.service.impl;

import com.shi.entity.Info;
import com.shi.entity.InfoVo;
import com.shi.mapper.InfoMapper;
import com.shi.service.InfoService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

/**
 * Author 史豪通
 * Date 2024/11/20 20:35
 */
@Service
public class InfoServiceImpl implements InfoService {
    @Resource
    InfoMapper infoMapper;

    @Override
    public List<InfoVo> getInfo(String startTime, String endTime) {
        ArrayList<InfoVo> infoVos = new ArrayList<>();

        List<Info> infos = infoMapper.select(startTime, endTime);
        // 插入一个info，便于最后的null处理
        infos.add(new Info(9999999999L, 9999999999L, LocalDateTime.now(), 1, 1));
/*        for (Info info : infos) {
            System.out.println(info);
        }*/

        if (!infos.isEmpty()) {
            // 初始化变量 (对象 时间 计数器)
            Info currInfo, nextInfo, firstInfo = null;
            long allTime = 0L, onTime = 0L, offTime = 0L;
            int count = 0, onCount = 0, offCount = 0;

            // 开始循环遍历
            for (int i = 0; i < infos.size(); i++) {
                // 当前对象
                currInfo = infos.get(i);
                // 第一个对象
                if (count == 0) {
                    firstInfo = currInfo;
                }
                // 下个对象
                if (i == infos.size() - 1) {
                    break;
                }
                nextInfo = infos.get(i + 1);

                count++;
                // 当前对象时间
                long currTime = currInfo.getOccurTime().toEpochSecond(ZoneOffset.UTC) * 1000 + currInfo.getMilliSecond();

                // objId不一致
                if (!currInfo.getObjId().equals(nextInfo.getObjId())) {
                    // 起始时间
                    long firstTime = firstInfo.getOccurTime().toEpochSecond(ZoneOffset.UTC) * 1000 + firstInfo.getMilliSecond();
                    // 总时间
                    if (currInfo == firstInfo) {
                        // 只有一个
                        long endTime_ = getTime(endTime);
                        allTime = endTime_ - firstTime;
                    } else {
                        allTime = currTime - firstTime;
                    }
                    // 最后一个status = 1 休息时间已计算好
                    if (currInfo.getStatus() == 1) {
                        // 运行时间
                        onTime = allTime - offTime;
                    } else {
                        // 休息时间
                        offTime = allTime - onTime;
                    }
                    // 计算次数
                    if (!firstInfo.getStatus().equals(currInfo.getStatus())) {
                        onCount = offCount = count >> 1;
                    } else if (currInfo.getStatus() == 1) {
                        offCount = count >> 1;
                        onCount = offCount + 1;
                    } else {
                        onCount = count >> 1;
                        offCount = onCount + 1;
                    }
                    infoVos.add(new InfoVo(currInfo.getObjId(), currInfo.getDevId(), onTime, offTime, onCount, offCount));

                    // 重新初始化
                    allTime = onTime = offTime = 0L;
                    count = onCount = offCount = 0;
                    continue;
                }

                // objId一致
                long nextTime = nextInfo.getOccurTime().toEpochSecond(ZoneOffset.UTC) * 1000 + nextInfo.getMilliSecond();
                // 当前status = 1
                if (currInfo.getStatus() == 1) {
                    onTime += nextTime - currTime;
                } else {
                    offTime += nextTime - currTime;
                }
            }

/*            for (InfoVo infoVo : infoVos) {
                System.out.println(infoVo);
            }*/
        }

        return infoVos;
    }

    /**
     * 时间字符串转换为毫秒
     * @param endTime
     * @return
     */
    private static long getTime(String endTime) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
        Date date = null;
        try {
            date = sdf.parse(endTime);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        return date.getTime();
    }
}
